import uuid
from datetime import datetime

from flask import Blueprint, render_template, request, jsonify, session
from flask_jwt_extended import jwt_required
from flask_login import login_required
from flask_restful import marshal, fields
from sqlalchemy import and_
from werkzeug.security import generate_password_hash

from applications.common import curd
from applications.common.curd import model_to_dicts, enable_status, disable_status, get_one_by_id, enable_is_on_sale, \
    disable_is_on_sale, auto_model_jsonify, update_userlevel
from applications.common.helper import ModelFilter
from applications.common.utils.getopenid import get_openid, token
from applications.common.utils.http import table_api, success_api, fail_api, wxuser_success_api, orders_api, \
    orders_out_api
from applications.common.utils.rights import authorize
from applications.common.utils.validate import xss_escape
from applications.exts import db
from applications.exts.cache import cache
from applications.exts.redis_command import getttl, getkeys
from applications.models import Role, Power, User, Goods, Classify, Orders, Wx_User_Address, Coupon
from applications.models.wx_orders import Orders_good_item
from applications.models.wx_user import WxUser
from applications.schemas import RoleOutSchema, PowerOutSchema2, WxUserOutSchema, GoodsOutSchema, OrdersOutSchema, \
    OrdersItemOutSchema
from applications.common.utils import upload as upload_curd

orders = Blueprint('orders', __name__, url_prefix='/orders')


# ========web===============
@orders.route('/')
@login_required
# flask 实现 Authorization请求报头认证
# @authorize("wxuser:role:main", log=True)
def main():
    return render_template('orders/main.html')


#   用户分页查询
@orders.route('/data')
@login_required
# @authorize("admin:user:main", log=True)
def data():
    # 获取请求参数
    gname = xss_escape(request.args.get('gname', type=str))
    gnum = xss_escape(request.args.get('gnum', type=str))
    # 查询参数构造
    mf = ModelFilter()
    if gname:
        mf.contains(field_name="gname", value=gname)
    if gnum:
        mf.contains(field_name="gnum", value=gnum)
    # if dept_id:
    #     mf.exact(field_name="dept_id", value=dept_id)
    # orm查询

    # 使用分页获取data需要.items
    orders = Orders.query.filter(mf.get_filter(model=Orders)).layui_paginate()
    count = orders.total
    # print('count:', count)
    # 返回apiupdataorders
    return table_api(data=model_to_dicts(schema=OrdersOutSchema, data=orders.items), count=count)


# # 修改
#
# # 删除用户
# @orders.route('/remove/<string:order_sn>', methods=["DELETE"])
# def delete(order_sn):
#     # user = User.query.filter_by(id=id).first()
#     # user.role = []
#
#     # res = User.query.filter_by(id=id).delete()
#
#     res = Orders.query.filter_by(order_sn=order_sn).delete()
#
#     db.session.commit()
#     print('res:', res)
#     if not res:
#         return fail_api(msg="删除失败")
#     return success_api(msg="删除成功")
#

#  编辑用户
@orders.route('/select/<string:order_sn>')
@login_required
# @authorize("admin:user:edit", log=True)
def select(order_sn):
    wxorder = Orders.query.filter(Orders.order_sn == order_sn).first()
    order_item=Orders_good_item.query.filter(Orders_good_item.order_sn == wxorder.order_sn).all()
    goods=[]
    for item in order_item:
        good = Goods.query.filter(Goods.id == item.goodsid).first()
        goods.append(good)
    wxuser = WxUser.query.filter(WxUser.openid == wxorder.openid).first()
    address = Wx_User_Address.query.get(wxorder.addressid)
    # print(wxuser.username)
    # roles = Role.query.all()
    # checked_roles = []
    # for r in user.role:
    #     checked_roles.append(r.id)
    return render_template('orders/select.html', wxorder=wxorder, goods=goods, wxuser=wxuser, address=address)


# 批量删除
@orders.route('/batchRemove', methods=["DELETE"])
# @authorize("admin:user:remove", log=True)
def batch_remove():
    order_sns = request.form.getlist('ids[]')
    for order_sn in order_sns:
        # wxuser = WxUser.query.filter_by(id=id).first()
        # user.role = []
        res = Orders.query.filter_by(order_sn=order_sn).delete()
        db.session.commit()
    return success_api(msg="批量删除成功")


#


# =========wx===============
# 添加orders,增加销量，减少库存


@orders.route('/addorders', methods=["POST"])
@jwt_required()
def addorders():
    getcode = -1
    addressid = -1
    req_json = request.json
    shop=req_json.get('shop')
    openid = req_json.get('openid')
    coupon_sn = req_json.get('coupon_sn')
    flag_integral=req_json.get('flag_integral')
    conupon = Coupon.query.filter(Coupon.coupon_sn == coupon_sn).first()
    submoney = 0.0
    if conupon:
        submoney = float(conupon.submoney)
    if flag_integral:
        submoney+=2.0
    order_sn = xss_escape(req_json.get('order_sn'))
    send_type = req_json.get('send_type')
    # 分类为外卖和店内取餐
    if send_type == 1:
        addressid = req_json.get('addressid')
    else:
        getcode = req_json.get('code')
    totalmoney = req_json.get('totalmoney')
    order = req_json.get('order')
    #     记录商品的数量
    oitem = []
    summoney = 0.0
    for item in order:
        orderitem = Orders_good_item()
        orderitem.order_sn = order_sn
        orderitem.goodsid = item.get('gid')
        orderitem.number = item.get('number')
        summoney += float(item.get('number') * item.get('good_price'))
        oitem.append(orderitem.to_dict())

    orderlist = []
    send_sn = str(uuid.uuid4())
    addorder = Orders()
    addorder.order_sn = order_sn
    addorder.goodsid = order[0].get('gid')
    addorder.openid = openid
    addorder.send_sn = send_sn
    addorder.send_type = send_type
    addorder.pay_status = 0
    # order——price是实际价格
    # yuan_price是使用优惠卷的价格
    addorder.order_price = summoney
    addorder.yuan_price = summoney - submoney
    addorder.code = getcode or '0'
    addorder.addressid = addressid or '0'
    addorder.store=shop
    orderlist.append(addorder.to_dict())
    integral={}
    integral['flag_integral']=flag_integral
    orderlist_items = []
    orderlist_items.append(orderlist)
    orderlist_items.append(oitem)
    orderlist_items.append(integral)
    strs = order_sn + openid

    print('orderlist_items:', orderlist_items)
    cache.set(f'{strs}', orderlist_items, timeout=910)
    return orders_api(order_sn=order_sn)


# 支付
@orders.route('/updataorders', methods=["POST"])
@jwt_required()
def updataorders():
    req_json = request.json
    openid = req_json.get("openid")
    order_sn = req_json.get("order_sn")
    strs = order_sn + openid
    orders = cache.get(f'{strs}')
    order = orders[0]
    order_item = orders[1]
    flag_integral=orders[2]
    summoney=order[0]['order_price']
    od = Orders()
    od.openid = order[0]['openid']
    od.order_sn = order[0]['order_sn']
    od.goodsid = order[0]['goodsid']
    od.order_price = order[0]['order_price']
    od.addressid = order[0]['addressid']
    od.yuan_price = order[0]['yuan_price']
    od.code = order[0]['code']
    od.send_type = order[0]['send_type']
    od.send_sn = order[0]['send_sn']
    od.store=order[0]['store']
    od.pay_status = 1

    for item in order_item:
        orderitem = Orders_good_item()
        orderitem.order_sn = order_sn
        orderitem.goodsid = item['goodsid']
        orderitem.number = item['number']
        good = Goods.query.get(item['goodsid'])
        if int(good.gnum) >= 1:
            if good.sales == 0:
                good.sales = item['number']
            else:
                good.sales = good.sales + item['number']
            try:
                nums = int(good.gnum) - item['number']
                if nums >= 0:
                    good.gnum = str(nums)

                    # db.session.add(addorder)
                    db.session.commit()

                    # print(1)
                    db.session.add(orderitem)
                    db.session.commit()
                else:
                    return orders_api(errno=1, msg='数量不够')
            except Exception as e:
                print(e)
                db.session.rollback()

        else:
            return orders_api(errno=1, msg='失败')
    try:

        db.session.add(od)
        db.session.commit()
        summoney=summoney*0.75
        cache.delete(f'{strs}')
        integral_status=update_userlevel(openid=openid,num=summoney)
        if flag_integral['flag_integral']=='True':
            rest=update_userlevel(openid=openid,num=-20)
        if integral_status and rest:
            print(111)
            pass
            # cache.delete(f'{strs}')
    except Exception as e:
        print(e)
        db.session.rollback()
    # 提取码过少
    orders = Orders.query.filter(and_(Orders.openid == openid, Orders.order_sn == order_sn)).first()
    code = orders.code
    goods = Goods.query.filter(Goods.id == orders.goodsid).first()
    good = goods.to_dict()

    return orders_api(errno=0, good=good, msg='支付成功', order_sn=order_sn, code=code)


# 传输数据格式化order


order_filed = {
    'oid': fields.Integer,
    'openid': fields.String(30),
    'order_sn': fields.String(44),
    'redatetime': fields.DateTime,
    'order_price': fields.Float,
    'yuan_price': fields.Float,
    'order_status': fields.Integer,
    'pay_status': fields.Integer,
    'send_status': fields.Integer,
    'send_type': fields.Integer,
    'send_sn': fields.String(40),
    'uid': fields.Integer,
    'code': fields.String(10),
    'store':fields.String(30),
    'goodsid': fields.Integer
}
# 传输goods
goods_filed = {
    'id': fields.Integer,
    'price': fields.Float,
    # 'gtype': fields.Integer,
    'gname': fields.String(35),
    'number': fields.Integer,
    'gphoto': fields.String(120),
    'sales': fields.Integer
}
#
order_item = {
    'id': fields.Integer,
    'order_sn': fields.String,
    'goodsid': fields.Integer,
    'number': fields.Integer
}


# 传输外卖订单列表
@orders.route('/pullorderslist', methods=["POST", "GET"])
@jwt_required()
def pullorderslist():
    req_json = request.json
    openid = req_json.get('openid')
    orders = Orders.query.filter(and_(Orders.send_type == 1, Orders.openid == openid)).all()
    orderslist = []
    for item in orders:
        shopgood = {}
        # print(type(item))

        order_items = Orders_good_item().query.filter(Orders_good_item.order_sn == item.order_sn).all()
        address = Wx_User_Address.query.filter(Wx_User_Address.id == item.addressid).first()
        # print('addressopenid:', address.openid)
        shopgood['order'] = dict(marshal(item, order_filed))
        # shopgood['good'] = dict(marshal(good, goods_filed))
        # model_to_dicts(schema=OrdersOutSchema, data=orders.items)
        goods = []
        order_it = []
        for i in order_items:
            good = Goods.query.get(i.goodsid)
            goods.append(good.to_dict())
            order_it.append(i.to_dict())
        shopgood['order_items'] = order_it
        shopgood['good'] = goods
        # shopgood['order_items'] = dict(model_to_dicts(schema=OrdersItemOutSchema, data=order_items))
        shopgood['address'] = address.to_dict()
        orderslist.append(shopgood)
    # print(orderslist)
    return orders_out_api(orderlist=orderslist)


# 传输店内订单列表
@orders.route('/pullorderslistin', methods=["POST", "GET"])
@jwt_required()
def pullorderslistin():
    req_json = request.json
    openid = req_json.get('openid')

    orders = Orders.query.filter(and_(Orders.send_type == 0, Orders.openid == openid)).all()
    orderslist = []
    for item in orders:
        shopgood = {}
        # good = Goods.query.get(order.goodsid)
        # go=model_to_dic
        # ts(GoodsOutSchema, data=good)
        # print(type(item))
        good = Goods.query.get(item.goodsid)
        order_items = Orders_good_item().query.filter(Orders_good_item.order_sn == item.order_sn).all()
        shopgood['order'] = dict(marshal(item, order_filed))
        shopgood['good'] = dict(marshal(good, goods_filed))
        # shopgood['order_items'] = dict(marshal(order_items, Orders_good_item))
        # order = model_to_dicts(OrdersOutSchema, data=item)
        # print('order[0]', order[0])
        # shopgood['order']=order[0]
        # shopgood['good'] = go[0]
        goods = []
        order_it = []
        for i in order_items:
            good = Goods.query.get(i.goodsid)
            goods.append(good.to_dict())
            order_it.append(i.to_dict())
        shopgood['order_items'] = order_it
        shopgood['good'] = goods
        # shopgood['order_items'] = dict(model_to_dicts(schema=OrdersItemOutSchema, data=order_items))
        orderslist.append(shopgood)
        # print(orderslist)
    return orders_out_api(orderlist=orderslist)


@orders.route('/orderenter', methods=["POST", "GET"])
@jwt_required()
def orderenter():
    flag = 0
    data = request.json
    oid = data.get("oid")
    # print(data)
    # order_sn = data.get("order_sn")
    orders = Orders.query.get(oid)
    # orders = Orders.query.filter(and_(Orders.uid == uid, Orders.pid == pid,Orders.order_sn==order_sn)).first()
    # print('orders', orders.order_status)
    if orders:
        orders.pay_type = 1
        orders.order_status = 1
        try:
            db.session.commit()
            flag = 1
        except Exception as e:
            print(e)
            db.session.rollback()
            flag = 0
    return orders_api(errno=flag)


# 传输取消支付的订单
@orders.route('/getredis', methods=["POST", "GET", "PUT"])
@jwt_required()
def getredis():
    req_json = request.json
    openid = req_json.get('openid')
    order_sn = xss_escape(req_json.get('order_sn'))
    strs = str(order_sn) + openid
    cacheorderlist = getkeys(openid)
    # print('keys',)
    temp = []
    for i in cacheorderlist:
        temp.append(cache.get(f'{i}'))
    # print('temp:', temp)
    if len(temp):
        tp = []
        # https://blog.csdn.net/weixin_41889416/article/details/109111179 #列出索引
        for index, item in enumerate(temp):
            order = item[0]
            print('count:', cacheorderlist[index])
            ttl = getttl(cacheorderlist[index]) - 10
            order_item = item[1]
            if len(item) == 0:
                return orders_out_api(errno=1)
            else:
                orders = []
                m = {}
                good = []
                order_items = []
                for item in order_item:
                    goods = Goods.query.get(item['goodsid'])
                    order_items.append(item)
                    good.append(goods.to_dict())
                m['order_items'] = order_items
                m['good'] = good
                m['order'] = order[0]
                m['ttl'] = ttl

                orders.append(m)
                # print('orders:', orders)
            tp.append(orders)
        # print('tp:',tp)
        return orders_out_api(orderlist=tp)
    else:
        return orders_out_api(errno=0, msg='没有订单')

    # ======================
    # waitorders = cache.get(f'{strs}') or []
    # # for i in waitorders:
    # #     print('waitorders:',i)
    # if len(waitorders):
    #     order=waitorders[0]
    #
    #     order_item=waitorders[1]
    #     if len(waitorders) == 0:
    #         return orders_out_api(errno=1)
    #     else:
    #         orders = []
    #         m = {}
    #         # goods = Goods.query.get(order[0]['goodsid'])
    #         # m['good'] = goods.to_dict()
    #         # m['order'] = order[0]
    #         # orders.append(m)
    #
    #         good=[]
    #         order_items=[]
    #         for item in order_item:
    #             goods = Goods.query.get(item['goodsid'])
    #             order_items.append(item)
    #             good.append(goods.to_dict())
    #         m['order_item']=order_items
    #         m['good']=good
    #         m['order']=order[0]
    #         m['ttl']=getttl(strs)-10
    #         orders.append(m)
    #         print('orders:',orders)
    #         # return orders_out_api(orderlist=orders)
    # else:
    #     return orders_out_api(errno=1,msg='没有订单')


#     支付redis里面的订单
# @orders.route('enterredis', methods=["POST", "GET"])
# @jwt_required()
# def enterredis():
#     req_json = request.json
#     order_sn = req_json.get('sn')
#     addressid = req_json.get('addressid')
#     wxcartsadd = cache.get('wxcartsadd')
#
#     print('wxcartsadd', wxcartsadd)
#     # {'id': None, 'openid': 'ocmg85A_-Bf-Gg_qkXthHHAXkqww', 'gid': 4, 'good_price': 10.0, 'good_gname': '咖啡',
#     #  'number': 1, 'good_photo': 'htt//127.0.0.1:5000/static/upload/goods/1e24d4d7-b50e-46c5-a400-679f1f683419.123.png',
#     #  'update_time': '', 'is_del': 0}
#
#     order = Orders()
#     order.order_sn = order_sn
#     order.order_price = wxcartsadd['good_price']
#     order.openid = wxcartsadd['openid']
#     order.goodsid = wxcartsadd['gid']
#     order.yuan_price = wxcartsadd['good_price']
#     order.addressid = addressid
#     order.code = -1
#     order.send_sn = '-1'
#     order.pay_status = 1
#     order.order_status = 1
#
#     db.session.add(order)
#     db.session.commit()
#
#     return orders_api()


@orders.route('/cancel', methods=["POST", "GET", "PUT"])
def ordercancel():
    req_json = request.json
    openid = req_json.get('openid')
    order_sn = xss_escape(req_json.get('order_sn'))
    strs = str(order_sn) + openid
    print(strs)
    waitorders = cache.get(f'{strs}') or []

    if len(waitorders):
        order = waitorders[0]
        order_item = waitorders[1]
        od = Orders()
        od.openid = order[0]['openid']
        od.order_sn = order[0]['order_sn']
        od.goodsid = order[0]['goodsid']
        od.order_price = order[0]['order_price']
        od.order_price = order[0]['order_price']
        od.addressid = order[0]['addressid']
        od.yuan_price = order[0]['yuan_price']
        od.code = order[0]['code']
        od.send_type = order[0]['send_type']
        od.send_sn = order[0]['send_sn']
        od.pay_status = 0
        od.order_status = 2
        for item in order_item:
            orderitem = Orders_good_item()
            orderitem.order_sn = order_sn
            orderitem.goodsid = item['goodsid']
            orderitem.number = item['number']
            good = Goods.query.get(item['goodsid'])
            if good:
                good.gnum = str(int(good.gnum) + item['number'])
                db.session.commit()
                print(1)
            try:
                db.session.add(orderitem)
                db.session.commit()
                print(2)
            except Exception as e:
                print(e)
                db.session.rollback()
                print(3)
                return orders_api(errno=1, msg='失败')
        try:
            db.session.add(od)
            db.session.commit()
            cache.delete(f'{strs}')
        except Exception as e:
            print(e)
            db.session.rollback()
        print(3)
        return orders_out_api(errno=0, msg='成功')
    else:
        print(4)
        return orders_out_api(errno=1, msg='失败')

